﻿using System.Text;

namespace extensions.common
{
    /// <summary>
    /// 字符串扩展类
    /// </summary>
    public static class StringExtension
    {
        /// <summary>
        /// 判断字符串是否不为 null、空字符串和空格
        /// </summary>
        /// <param name="str">当前字符串</param>
        /// <returns>返回 true 表示有效字符串，反之返回 false </returns>
        public static bool Valid(this string? str)
        {
            return !string.IsNullOrWhiteSpace(str);
        }

        /// <summary>
        /// 为当前字符串追加指定的字符串。
        /// skipRepeat 为 true 时，toAppend 不应包含分隔符，会影响重复判断
        /// </summary>
        /// <param name="current">当前字符串</param>
        /// <param name="toAppend">追加的字符串</param>
        /// <param name="skipRepeat">是否跳过重复（默认否）</param>
        /// <param name="separator">拼接字符（默认英文逗号）</param>
        /// <returns>字符串（不管传参如何，至少会返回空字符串）</returns>
        public static string Append(this string? current, 
            string? toAppend, bool skipRepeat = false, char separator = ',')
        {
            if (string.IsNullOrWhiteSpace(current)) 
                return string.IsNullOrWhiteSpace(toAppend) ? string.Empty : toAppend;

            if (string.IsNullOrWhiteSpace(toAppend))
                return current;

            if (skipRepeat && current.Split(separator).Contains(toAppend))
                return current;

            var sb = new StringBuilder(current);

            if (!current.EndsWith(separator))
                sb.Append(separator);

            return sb.Append(toAppend).ToString();
        }

        /// <summary>
        /// 将当前字符串分割为可遍历对象。
        /// 目标类型支持所有值类型，以及 string、char、DateTime、bool 等简单类型，不支持 Guid、自定义类等复杂类型
        /// </summary>
        /// <typeparam name="T">分割后要转换的目标类型</typeparam>
        /// <param name="str">当前字符串</param>
        /// <param name="separator">分割字符（默认英文逗号）</param>
        /// <returns>目标类型的 IEnumerable 对象</returns>
        public static IEnumerable<T> Split<T>(this string? str, char separator = ',')
        { 
            if (string.IsNullOrWhiteSpace(str))
                return [];
            
            return str
                .Split(separator, StringSplitOptions.RemoveEmptyEntries)
                .Select(it => (T)Convert.ChangeType(it, typeof(T)));
        }

        /// <summary>
        /// 将当前 UTF-8 字符串转换为 Base64 格式
        /// </summary>
        /// <param name="str">当前字符串</param>
        /// <returns>Base64 字符串（当前字符串是无效的话统一返回空字符串）</returns>
        public static string Utf8ToBase64(this string? str)
        {
            if (string.IsNullOrWhiteSpace(str))
                return string.Empty;

            var bytes = Encoding.UTF8.GetBytes(str);
            return Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// 将当前 Base64 字符串转换为 UTF-8 格式
        /// </summary>
        /// <param name="str">当前字符串</param>
        /// <returns>UTF-8 字符串（当前字符串是无效的话统一返回空字符串）</returns>
        public static string Base64ToUtf8(this string? str)
        { 
            if (string.IsNullOrWhiteSpace(str))
                return string.Empty;

            var bytes = Convert.FromBase64String(str);
            return Encoding.UTF8.GetString(bytes);
        }
    }
}
